package com.ljt.realtimebusCC;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ljt.realtimebusCC.domain.ArrivalTimeVO;
import com.ljt.realtimebusCC.domain.BusRouteVO;
import com.ljt.realtimebusCC.domain.BusVehicle;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.ConnectException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.concurrent.TimeoutException;

public class BusTrackerBasic extends JFrame {
    private JList<String> lineList;
    private DefaultListModel<String> listModel;
    private JTextField routeNameField;
    private JTextField stopNameField;
    private JTextArea resultArea;
    private List<BusRouteVO> routeList; // 新增成员变量存储线路数据

    /**
     * 调用接口:查询所有线路
     * @param e
     */
    private void fetchAllLines(ActionEvent e) {
        new SwingWorker<List<BusRouteVO>, Void>() {
            String result;
            Exception exception;

            @Override
            protected List<BusRouteVO> doInBackground() throws Exception {
                try {
                    result = HttpRequest.get("http://localhost:8123/api/allline")
                            .execute()
                            .body();
                    return parseResponse(result);
                } catch (Exception ex) {
                    exception = ex;
                    return null;
                }
            }

            @Override
            protected void done() {
                try {
                    if (exception != null) {
                        throw exception;
                    }

                    List<BusRouteVO> routes = get();
                    routeList = get(); // 保存线路数据到成员变量
                    listModel.clear();
                    for (BusRouteVO route : routes) {
                        String lineInfo = String.format("%s %s [%s] 站点数：%d",
                                route.getRouteName(),
                                route.getOperatingHours(),
                                route.getStopNameList().get(0) + "→" +
                                        route.getStopNameList().get(route.getStopNameList().size()-1),
                                route.getStopNameList().size());
                        listModel.addElement(lineInfo);
                    }

                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(BusTrackerBasic.this,
                            "获取线路失败: " + ex.getMessage(),
                            "错误",
                            JOptionPane.ERROR_MESSAGE);
                }
            }
        }.execute();
    }

    /**
     * 配合fetchAllLines函数的解析结果
     * @param json
     * @return
     */
    private List<BusRouteVO> parseResponse(String json) {
        JSONObject resp = JSONUtil.parseObj(json);
        if (resp.getInt("code") != 0) {
            throw new RuntimeException(resp.getStr("msg"));
        }

        JSONArray data = resp.getJSONArray("data");
        return JSONUtil.toList(data, BusRouteVO.class);
    }

    /**
     * 主界面
     */
    public BusTrackerBasic() {
        setTitle("公交追踪系统 - 基础版");
        setSize(1000, 500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout(10, 10));
        initComponents();
    }

    /**
     * 初始化主界面
     */
    private void initComponents() {
        // 顶部面板：线路列表
        JPanel topPanel = createLinePanel();

        // 中间面板：实时位置查询
        JPanel middlePanel = createPositionPanel();

        // 底部面板：到站时间查询
        JPanel bottomPanel = createArrivalPanel();

        // 结果展示区域
        resultArea = new JTextArea(10, 50);
        resultArea.setEditable(false);
        resultArea.setBorder(BorderFactory.createTitledBorder("查询结果"));

        // 组合布局
        add(topPanel, BorderLayout.NORTH);
        add(middlePanel, BorderLayout.CENTER);
        add(bottomPanel, BorderLayout.SOUTH);
        add(new JScrollPane(resultArea), BorderLayout.EAST);

        lineList.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) {
                if (evt.getClickCount() == 2) { // 检测双击事件
                    showSelectedLineStops();
                }
            }
        });
    }

    /**
     * 显示选中线路的所有站点
     */
    private void showSelectedLineStops() {
        int selectedIndex = lineList.getSelectedIndex();
        if (selectedIndex == -1) {
            JOptionPane.showMessageDialog(this,
                    "请先选择一条线路",
                    "提示",
                    JOptionPane.INFORMATION_MESSAGE);
            return;
        }

        BusRouteVO selectedRoute = routeList.get(selectedIndex);
        List<String> stops = selectedRoute.getStopNameList();

        // 构建显示内容
        StringBuilder sb = new StringBuilder();
        sb.append("线路【").append(selectedRoute.getRouteName()).append("】全部站点：\n");
        for (int i = 0; i < stops.size(); i++) {
            sb.append(i+1).append(". ").append(stops.get(i)).append("\n");
        }

        // 使用对话框显示（带滚动条）
        JTextArea textArea = new JTextArea(sb.toString(), 15, 30);
        textArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(textArea);
        JOptionPane.showMessageDialog(this, scrollPane, "站点列表", JOptionPane.PLAIN_MESSAGE);
    }

    private JPanel createLinePanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createTitledBorder("线路查询"));

        listModel = new DefaultListModel<>();
        lineList = new JList<>(listModel);

        JButton fetchLinesBtn = new JButton("获取全部线路");
        // fetchLinesBtn.addActionListener(this::showMockLines);
        fetchLinesBtn.addActionListener(this::fetchAllLines);

        panel.add(fetchLinesBtn, BorderLayout.NORTH);
        panel.add(new JScrollPane(lineList), BorderLayout.CENTER);
        return panel;
    }

    private JPanel createPositionPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createTitledBorder("实时位置查询"));

        JPanel inputPanel = new JPanel();
        inputPanel.add(new JLabel("路线名称:"));
        routeNameField = new JTextField(10);
        inputPanel.add(routeNameField);

        JButton positionBtn = new JButton("查询实时位置");
        positionBtn.addActionListener(this::fetchRealTimePosition);

        inputPanel.add(positionBtn);
        panel.add(inputPanel, BorderLayout.NORTH);
        return panel;
    }


    // 新增实时位置查询方法
    private void fetchRealTimePosition(ActionEvent e) {
        String routeName = routeNameField.getText().trim();
        if (routeName.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请输入要查询的路线名称", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

        new SwingWorker<List<BusVehicle>, Void>() {
            String result;
            Exception exception;

            @Override
            protected List<BusVehicle> doInBackground() throws Exception {
                try {
                    String encodedRouteName = URLEncoder.encode(routeName, StandardCharsets.UTF_8);
                    String url = "http://localhost:8123/api/position/" + encodedRouteName;

                    result = HttpRequest.get(url)
                            .timeout(5000)
                            .execute()
                            .body();
                    return parseVehicleResponse(result);
                } catch (Exception ex) {
                    exception = ex;
                    return null;
                }
            }

            @Override
            protected void done() {
                try {
                    if (exception != null) {
                        throw exception;
                    }

                    List<BusVehicle> vehicles = get();
                    showVehicleResults(vehicles);

                } catch (Exception ex) {
                    resultArea.setText("查询失败: " + ex.getMessage());
                }
            }
        }.execute();
    }

    // 新增响应解析方法
    private List<BusVehicle> parseVehicleResponse(String json) {
        JSONObject resp = JSONUtil.parseObj(json);
        if (resp.getInt("code") != 0) {
            throw new RuntimeException(resp.getStr("msg"));
        }

        JSONArray data = resp.getJSONArray("data");
        return JSONUtil.toList(data, BusVehicle.class);
    }

    // 新增结果显示方法
    private void showVehicleResults(List<BusVehicle> vehicles) {
        if (vehicles == null || vehicles.isEmpty()) {
            resultArea.setText("该线路当前无车辆运行");
            return;
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        StringBuilder sb = new StringBuilder();
        sb.append("实时位置查询结果：\n");

        for (BusVehicle vehicle : vehicles) {
            sb.append("车辆ID: ").append(vehicle.getVehicleId()).append("\n")
                    .append("所属线路ID: ").append(vehicle.getRouteId()).append("\n")
                    .append("当前位置: 纬度 ").append(vehicle.getCurrentLatitude())
                    .append(", 经度 ").append(vehicle.getCurrentLongitude()).append("\n")
                    .append("最后更新时间: ").append(sdf.format(vehicle.getLastUpdateTime()))
                    .append("\n------------------------\n");
        }

        resultArea.setText(sb.toString());
    }


    private JPanel createArrivalPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createTitledBorder("到站时间查询"));

        JPanel inputPanel = new JPanel();
        inputPanel.add(new JLabel("站点名称:")); // 修改标签
        stopNameField = new JTextField(10); // 修改字段
        inputPanel.add(stopNameField);

        JButton arrivalBtn = new JButton("查询到站时间"); // 修改按钮文本
        arrivalBtn.addActionListener(this::fetchArrivalTime); // 绑定新事件

        inputPanel.add(arrivalBtn);
        panel.add(inputPanel, BorderLayout.NORTH);
        return panel;
    }

    // 新增到站时间查询方法
    private void fetchArrivalTime(ActionEvent e) {
        String stopName = stopNameField.getText().trim();
        if (stopName.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请输入站点名称", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

        new SwingWorker<List<ArrivalTimeVO>, Void>() {
            String result;
            Exception exception;
            JButton btn = (JButton) e.getSource();

            @Override
            protected List<ArrivalTimeVO> doInBackground() throws Exception {
                try {
                    btn.setEnabled(false);
                    String encodedStop = URLEncoder.encode(stopName, StandardCharsets.UTF_8);
                    String url = "http://localhost:8123/api/arrival/" + encodedStop;

                    result = HttpRequest.get(url)
                            .timeout(8000)
                            .execute()
                            .body();
                    return parseArrivalResponse(result);
                } catch (Exception ex) {
                    exception = ex;
                    return null;
                } finally {
                    btn.setEnabled(true);
                }
            }

            @Override
            protected void done() {
                try {
                    if (exception != null) throw exception;

                    List<ArrivalTimeVO> arrivals = get();
                    showArrivalResults(arrivals);

                } catch (ConnectException ce) {
                    resultArea.setText("无法连接服务器，请检查网络");
                } catch (TimeoutException te) {
                    resultArea.setText("请求超时，请稍后重试");
                } catch (JSONException je) {
                    resultArea.setText("数据解析失败：" + je.getMessage());
                } catch (Exception ex) {
                    resultArea.setText("查询出错：" + ex.getMessage());
                }
            }
        }.execute();
    }

    // 新增到站时间解析方法
    private List<ArrivalTimeVO> parseArrivalResponse(String json) {
        JSONObject resp = JSONUtil.parseObj(json);
        if (resp.getInt("code") != 0) {
            throw new RuntimeException(resp.getStr("msg"));
        }

        JSONArray data = resp.getJSONArray("data");
        return JSONUtil.toList(data, ArrivalTimeVO.class);
    }

    // 新增到站结果显示方法
    private void showArrivalResults(List<ArrivalTimeVO> arrivals) {
        if (arrivals == null || arrivals.isEmpty()) {
            resultArea.setText("该站点暂无即将到站的车辆");
            return;
        }

        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        StringBuilder sb = new StringBuilder();
        sb.append("到站时间预测：\n");

        for (ArrivalTimeVO arrival : arrivals) {
            long minutes = ChronoUnit.MINUTES.between(
                    Instant.now(),
                    arrival.getEstimatedArrivalTime().toInstant()
            );

            sb.append("线路：").append(arrival.getRouteName()).append("\n")
                    .append("预计到达：").append(sdf.format(arrival.getEstimatedArrivalTime()))
                    .append(" (").append(minutes).append("分钟后)\n")
                    .append("车辆ID：").append(arrival.getVehicleId()).append("\n")
                    .append("最后计算时间：").append(sdf.format(arrival.getLastCalculatedTime()))
                    .append("\n------------------------\n");
        }

        resultArea.setText(sb.toString());
    }



    private void showMockLines(ActionEvent e) {
        listModel.clear();
        listModel.addElement("1路：城站火车站-西湖景区");
        listModel.addElement("2路：武林广场-西溪湿地");
        listModel.addElement("4路：火车东站-钱江新城");
        listModel.addElement("7路：灵隐寺-吴山广场");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new BusTrackerBasic().setVisible(true);
        });
    }
}